﻿using KinonekoSoftware.Extensions.Ioc;
using KinonekoSoftware.JuXiaoYouDB.SubSystem.Categories;
using KinonekoSoftware.Studio;
using KinonekoSoftware.JuXiaoYouDB.Core;
using KinonekoSoftware.JuXiaoYouDB.Objects;
using LiteDB;

namespace KinonekoSoftware.JuXiaoYouDB.SubSystem
{
    public sealed partial class GlossaryDB : Disposable, IDispoableDatabase
    {
        
        //-------------------------------------------------------------
        //
        //          ReadOnly Fields
        //
        //-------------------------------------------------------------
        private readonly LiteDatabase                  _Database;
        private readonly ILiteCollection<Glossary>     _GlossaryCollection;
        private readonly ILiteCollection<InstanceType> _InstanceTypeCollection;
        private readonly string                        _Directory;
        
        
        //-------------------------------------------------------------
        //
        //          Fields
        //
        //-------------------------------------------------------------
        
        private static bool       _IsCreated;
        private static GlossaryDB _Instance;
        
        private int  _VersionGlossary;
        private bool _IsDisposed;
        private bool _HasInstanceTypeCollection;

        
        //-------------------------------------------------------------
        //
        //          Constructors
        //
        //-------------------------------------------------------------
        public GlossaryDB(LiteDatabase database, string directory)
        {
            _Database                  = database;
            _Directory                 = directory;
            _IsDisposed                = false;
            _HasInstanceTypeCollection = database.CollectionExists(CollectionNames.InstanceType);
            _GlossaryCollection        = database.GetCollection<Glossary>(CollectionNames.Glossary);
            _InstanceTypeCollection    = database.GetCollection<InstanceType>(CollectionNames.InstanceType);
        }
        //-------------------------------------------------------------
        //
        //          Override Methods
        //
        //-------------------------------------------------------------
        protected override void ReleaseUnmanagedResources()
        {
            if (!_IsCreated || _Database is null)
            {
                return;
            }
            
            //
            //
            _Database.Checkpoint();
            _Database.Checkpoint();
            _Database.Dispose();
            _IsCreated  = true;
            _IsDisposed = true;
            
            //
            //
            base.ReleaseUnmanagedResources();
        }

        protected override void ReleaseManagedResources()
        {
            _IsDisposed = true;
            base.ReleaseManagedResources();
        }

        //-------------------------------------------------------------
        //
        //          Public Methods
        //
        //-------------------------------------------------------------

        
        //-------------------------------------------------------------
        //
        //          Properties
        //
        //-------------------------------------------------------------

        public string Workspace => _Directory;
        public bool   IsAlive   => !_IsDisposed;
        
        //-------------------------------------------------------------
        //
        //          Static Property
        //
        //-------------------------------------------------------------
        public static GlossaryDB Instance
        {
            get
            {
                if (!_IsCreated || _Instance is null)
                {
                    var directory = Ioc.Get<IRepositoryManager>().Directory;
                    var fileName  = Path.Combine(directory, FileNames.GlossaryDB);
                    var database  = new LiteDatabase(fileName);
                    
                    _Instance  = new GlossaryDB(database, fileName);
                    _IsCreated = true;
                }

                return _Instance;
            }
        }

        public static bool IsCreated => _IsCreated;
    }
}